/**
  * iRun - Utility for for sending run rs to an iPod
  * Based off of iRecovery
  * Copyright (C) 2008 - 2009 westbaer, tom3q
  * 
  * This program is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
  * the Free Software Foundation, either version 3 of the License, or
  * (at your option) any later version.
  * 
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  * 
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  **/

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <usb.h>
#define RECOVERY_MODE 0x1281

struct usb_dev_handle *globalDevPhone;

struct usb_dev_handle *iUSBInit(int devid)
{
	struct usb_dev_handle *devPhone = 0;
	struct usb_device *dev;
	struct usb_bus *bus;

	usb_init();
	usb_find_busses();
	usb_find_devices();

	for(bus = usb_get_busses(); bus; bus = bus->next) {
		//printf("Found BUS\n");
		for(dev = bus->devices; dev; dev = dev->next) {
			//printf("\t%4.4X %4.4X\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
			if(dev->descriptor.idVendor == 0x5AC && dev->descriptor.idProduct == devid) {
				// z0mg!!!! iPhone 4th Generation
//				printf("Found iPhone/iPod in DFU 2.0\n");
				devPhone = usb_open(dev);
			}
		}
	}

	return devPhone;
}

void sendCommand(char *cmd) {
	struct usb_dev_handle *devPhone;
	char *sendbuf;
	devPhone = iUSBInit(RECOVERY_MODE);
	if(devPhone == 0) {
		printf("No iPhone/iPod found.\n");
		exit(EXIT_FAILURE);
	}
	sendbuf = malloc(160);
	int length = (int)(((strlen(cmd)-1)/0x10)+1)*0x10;
	memset(sendbuf, 0, length);
	memcpy(sendbuf, cmd, strlen(cmd));
	if(!usb_control_msg(devPhone, 0x40, 0, 0, 0, sendbuf, length, 1000)) {
		printf("[ ERROR ] %s", usb_strerror());
	}
	free(sendbuf);
}

int iShowUsage(void)
{
		printf("./iRun [args]\n");
		printf("\t-r\t\t\tsend run rs to an iPod in recovery mode\n");
		printf("\t-d\t\t\twait for an ipod touch 2g in recovery mode to send run rs.\n\n");
}

/*
 * Main function of the application
 */
int main(int argc, char *argv[])
{
	printf("iRun - Run rs booter\n");
	printf("By Evan Coleman (fiftyfour123)\n");
	printf("special thanks to chronic, westbaer, pod2g and tom3q for making iRecovery which this is based off of\n");
	printf("thanks to The iPhone-dev team for run rs and redsn0w\n\n");
	if(argc < 2) {
		iShowUsage();
		exit(EXIT_FAILURE);
	}

	if(argv[1][0] != '-') {
		iShowUsage();
		exit(EXIT_FAILURE);
	}
	
	if(strcmp(argv[1], "-d") == 0) {
		struct usb_dev_handle *devPhone;
		char *sendbuf;
			while (1) {
				devPhone = iUSBInit(RECOVERY_MODE);
				if(devPhone == 0) {

				} else {
					sendCommand("run rs");
					usb_close(devPhone);
				}
			}
	} else if(strcmp(argv[1], "-r") == 0) {
		struct usb_dev_handle *devPhone;
		char *sendbuf;
				devPhone = iUSBInit(RECOVERY_MODE);
				if(devPhone == 0) {
					printf("iPod in recovery mode not found.\n");
				} else {
					sendCommand("run rs");
					usb_close(devPhone);
				}
	} else {
		struct usb_dev_handle *devPhone;
		char *sendbuf;
			while (1) {
				devPhone = iUSBInit(RECOVERY_MODE);
				if(devPhone == 0) {

				} else {
					sendCommand("run rs");
					usb_close(devPhone);
				}
			}
	}
	return 0;
}
